package pl.streamsoft.currencyApp.dao;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;

import pl.streamsoft.currencyApp.model.Country;
import pl.streamsoft.currencyApp.model.Currency;

public class CountryDAO implements ICountryDAO{

	private HibernateUtil hibernateUtil;
	
	public CountryDAO(){
		this.hibernateUtil = new HibernateUtil();
	}
	
	@Override
	public void insertCountryIntoDB(Country country) throws RuntimeException{
		Set<Currency> setOFCurrencies = new HashSet<Currency>();
		setOFCurrencies.addAll(country.getCurrencyList());
		
		country.getCurrencyList().clear();
		country.getCurrencyList().addAll(setOFCurrencies);
		
		Session session = hibernateUtil.getOpenedSession();
		try{
			session.saveOrUpdate(country);
			hibernateUtil.closeSession();
		}
		catch(Exception e){
			hibernateUtil.rollBackTransaction();
			hibernateUtil.closeSession();
			throw new RuntimeException("Can't insert country into database!");
		}
	}

	@Override
	public Country getCountryFromDB(String name) throws RuntimeException {
		try{
			Session session = hibernateUtil.getOpenedSession();
			Query query = session.getNamedQuery("Country.whereNameIsLike");
			
			//caching query added
			query.setCacheable(true);
			
			query.setString(0, name);
			query.setMaxResults(1);
						
			Country country = (Country) query.uniqueResult();
			hibernateUtil.closeSession();
			return country;
		}
		catch(Exception e){
			hibernateUtil.closeSession();
			throw new RuntimeException("Can't get country from database!");
		}
	}

	@Override
	public void deleteCountry(String name) throws RuntimeException{
		try {
			Session session = hibernateUtil.getOpenedSession();
			Query query = session.getNamedQuery("Country.deleteWhereNameIsLike");
			query.setString(0, name);
			query.executeUpdate();
			hibernateUtil.closeSession();
		} 
		catch (Exception e) {
			hibernateUtil.rollBackTransaction();
			hibernateUtil.closeSession();
			throw new RuntimeException("Can't delete country!");
		}
	}

	@Override
	public List<Country> getAllCountries() throws RuntimeException{
		try{
			Session session = hibernateUtil.getOpenedSession();
			Query query = session.getNamedQuery("Country.allCountries");
			//caching query added
			query.setCacheable(true);
			List<Country> listOfCurrencies = (List<Country>) query.list();
			
			hibernateUtil.closeSession();
			return listOfCurrencies;
		}
		catch(Exception e){
			hibernateUtil.closeSession();
			throw new RuntimeException("Can't get all countries!");
		}
	}

	@Override
	public List<Currency> getAllCountryCurrencies(String nameOfCountry) throws RuntimeException {
		try{
			long countryId = getCountryFromDB(nameOfCountry).getId();
			Session session = hibernateUtil.getOpenedSession();
			
			Country country = (Country) session.get(Country.class, countryId);
			
			hibernateUtil.closeSession();
			return country.getCurrencyList();
		}
		catch(Exception e){
			hibernateUtil.closeSession();
			throw new RuntimeException("Can't get currencies where country name is "+nameOfCountry);
		}
	}

	@Override
	public void deleteAllCountriesFromDB() throws RuntimeException {
		Session session = hibernateUtil.getOpenedSession();
		try{
			Query query = session.getNamedQuery("Country.deleteAllCountries");
			query.executeUpdate();
						
			hibernateUtil.closeSession();
		}
		catch(Exception e){
			hibernateUtil.rollBackTransaction();
			hibernateUtil.closeSession();
			throw new RuntimeException("Can't delete all counries from database!");
		}
	}

	

}
